pub mod array;
pub mod bool;
pub mod buck_string;
pub mod decode;
pub mod double;
pub mod encode;
pub mod error;
pub mod integer;
pub mod map;
pub mod null;
pub mod set;
pub mod simple_error;
pub mod simple_string;

use crate::resp::array::RespArray;
use crate::resp::buck_string::{BuckString, RespNullBulkString};
use crate::resp::error::RespError;
use crate::resp::map::RespMap;
use crate::resp::null::{RespNull, RespNullArray};
use crate::resp::set::RespSet;
use crate::resp::simple_error::SimpleError;
use crate::resp::simple_string::SimpleString;
use bytes::BytesMut;
use enum_dispatch::enum_dispatch;

const CRLF: &[u8] = b"\r\n";
const CRLF_LEN: usize = CRLF.len();

#[enum_dispatch]
pub trait RespEncode {
    fn encode(self) -> Vec<u8>;
}

pub trait RespDecode: Sized {
    const PREFIX: &'static str;
    fn decode(buf: &mut BytesMut) -> Result<Self, RespError>;
    fn expect_length(buf: &[u8]) -> Result<usize, RespError>;
}

#[enum_dispatch(RespEncode)]
#[derive(Debug, PartialEq, Clone)]
pub enum RespFrame {
    SimpleString(SimpleString),
    Error(SimpleError),
    Integer(i64),
    BulkString(BuckString),
    NullBulkString(RespNullBulkString),
    Array(RespArray),
    Null(RespNull),
    NullArray(RespNullArray),
    Boolean(bool),
    Double(f64),
    Map(RespMap),
    Set(RespSet),
}
